package com.ztc.util;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.Borders;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.VerticalAlign;
import org.apache.poi.xwpf.usermodel.XWPFAbstractNum;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFFooter;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFNumbering;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFStyle;
import org.apache.poi.xwpf.usermodel.XWPFStyles;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFldChar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHeightRule;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;

import com.ztc.bean.TD;

/**
 * @类名：HtmlToWordUtil.java
 * @作者：李晓平
 * @时间：2018年7月4日 下午4:50:32
 * @描述：富文本html转成word
 */
public class HtmlToWordUtil {
	
	private boolean isHoldStyle = false;
	
	private double line = 1.5;
	
	final int EMU = 9525;
	
	private static final String COMMON_FONTSIZE = "24"; //小四
	private static final String COMMON_FONTSIZE_TATBLE_TITLE = "21";//五号
	private static final String COMMON_FONTSIZE_TATBLE_CONTENT = "18";//小五
	
	private static final String[] holdStyleTitle = new String[]{"正文", "封面", "明细表封面", "委托人签章页", "被评估单位签章页", "委托人信息", "评估报告日", "资产评估师承诺函"};
	
	private List<String> holdStyleTitleList = Arrays.asList(holdStyleTitle);
	
	private String listStyleType = "";//行号类型
	private BigInteger numId = null;//自动编号id
	
	private String currentAuthName = "";
	
	public static void main(String[] args) {		
		try {
			String str = "<table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table>";
//			str = "<html><body>" + str + "</body><html>";
			org.jsoup.nodes.Document doc = Jsoup.parse(str, "utf-8");
			Elements tableEle = doc.getElementsByTag("table");
			Elements trs = tableEle.get(0).getElementsByTag("tr");
			trs.get(0).remove();
			System.out.println(trs.size());
			Elements tds = trs.get(1).getElementsByTag("td");
			for(int i = 0; i< tds.size();i++){
				if(i==0)
					tds.get(i).remove();
			}
			String unitStr = "<tr><td>金额单位：人民币</td></tr>";
			trs.get(0).before(unitStr);
			System.out.println(tds.size());
			System.out.println(tableEle.outerHtml());
//			String htmlStr = "<table><tr><td colspan=2 rowspan=2>1</td><td colspan=3>2</td><td>3</td></tr><tr><td>2</td><td>3</td><td>4</td><td>5</td></tr><tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td></tr></table>";
//			String htmlStr = "<html><body><p style='line-height: 1.5em; text-align: center; text-indent: 0em;'><span style='font-size:16px;line-height:150%;font-family: 宋体'>居中</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>一、本资产评估报告依据财政部发布的资产评估基本准则和<img width=30 height=20 src='http://192.168.10.72/project_ztc/imagztc/img/20180702/1530503584097093545.png' title='/1530503584097093545.png' alt='QQ截图20151017173450.png.png'/>中国资产评估协会发布的资产评估执业准则和职业道德准则编制。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>二、委托人或者其他资产评估报告使用人应当按照法律、行政法规规定及本资产评估报告载明的使用范围使用资产评估报告；委托人或者其他资产评估报告使用人未按前述要求使用资产评估报告的，本资产评估机构及资产评估师不承担责任。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>本资产评估报告仅供委托人、资产评估委托合同中约定的其他资产评估报告使用人和法律、行政法规规定的资产评估报告使用人使用；除此之外，其他任何机构和个人不能成为资产评估报告的使用人。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>本资产评估机构及资产评估师提示资产评估报告使用人应当正确理解评估结论，评估结论不等同于评估对象可实现价格，评估结论不应当被认为是对评估对象可实现价格的保证。</span></p><p style='text-indent: 32px; text-align: center; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'><img src='http://192.168.10.72/project_ztc/imagztc/img/20180702/1530503584097093545.png' title='1530503584097093545.png' alt='QQ截图20151017173450.png.png'/></span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>三、本资产评估机构及资产评估师坚持独立、客观和公正的原则，遵守法律、行政法规和资产评估准则，并对所出具的资产评估报告依法承担责任。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>四、评估对象涉及的资产、负债清单由委托人、被评估单位申报并经其采用签名、盖章或法律允许的其他方式确认；委托人和其他相关当事人依法对其提供资料的真实性、完整性、合法性负责。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>五、本资产评估机构及资产评估师与资产评估报告中的评估对象没有现存或者预期的利益关系；与相关当事人没有现存或者预期的利益关系，对相关当事人不存在偏见。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;line-height:150%;font-family: 宋体'>六、资产评估师<span style='background:yellow;background:yellow'>已经（或者未）</span>对资产评估报告中的评估对象及其所涉及资产进行现场调查；已经对评估对象及其所涉及资产的法律权属状况给予必要的关注，对评估对象及其所涉及资产的法律权属资料进行了查验，对已经发现的问题进行了如实披露，<span style='background:yellow;background:yellow'>并且已提请委托人及其他相关当事人完善产权以满足出具资产评估报告的要求</span>。</span></p><p style='text-indent: 32px; line-height: 1.5em;'>    <span style='font-size:16px;font-family:宋体'>七、本资产评估机构出具的资产评估报告中的分析、判断和结论受资产评估报告中假设和限制条件的限制，资产评估报告使用人应当充分考虑资产评估报告中载明的假设、限制条件、特别事项说明及其对评估结论的影响。</span></p><p style=' line-height: 1.5em;'>    <span style='font-size:16px;font-family:宋体'></span></p><table width='1733'>    <tbody>        <tr class='firstRow'>            <th valign='null' width='151'></th>            <th width='263'></th>            <th width='462'></th>            <th width='447'></th>            <th width='408'></th>        </tr>        <tr>            <th valign='null' width='151'></th>            <td valign='top' style='word-break: break-all;' width='263'>                <strong>id</strong>            </td>            <td valign='top' style='word-break: break-all;' width='462'>                name            </td>            <td valign='top' style='word-break: break-all;' width='447'>                value            </td>            <td valign='top' style='word-break: break-all;' width='408'>                desc            </td>        </tr>        <tr>            <th valign='null' width='151'></th>            <td valign='top' style='word-break: break-all;' width='263'>                1            </td>            <td valign='top' style='word-break: break-all;' width='462'>                <p>  张              </p>                <p>                    三                </p>            </td>            <td valign='top' style='word-break: break-all;' width='447' align='center'>                李四            </td>            <td valign='top' style='word-break: break-all;' width='408'>                描述            </td>        </tr>        <tr>            <th valign='null' width='151'></th>            <td valign='top' width='263'>                <img src='http://192.168.10.72/project_ztc/imagztc/img/20180704/1530671834625080751.png' title='1530671834625080751.png' alt='1.png.png' width='32' height='30'/>            </td>            <td valign='top' width='462'></td>            <td valign='top' width='447'></td>            <td valign='top' width='408'></td>        </tr>    </tbody></table><p style=' line-height: 1.5em;'>    <span style='font-size:16px;font-family:宋体'></span><br/></p><body></html>";
//			String htmlStr = "<p style='margin-bottom:0;margin-bottom:0;text-indent: 32px;line-height:150%'>    <span style='font-size:16px;line-height:150%;font-family:宋体;background:yellow;background:yellow'>资产评估委托合同约定的其他评估报告使用人包括×××，其概况如下。</span></p><p style='margin-bottom:0;margin-bottom:0;text-indent: 32px;line-height:150%'>    <span style='font-size:16px;line-height: 150%;background:yellow;background:yellow'>1.</span><span style='font-size:16px;line-height:150%;font-family:宋体;background:yellow;background:yellow'>名称：</span></p><p style='text-indent:32px;line-height:150%;text-autospace: none'>    <span style='font-size:16px;line-height:150%'>2.</span><span style='font-size:16px;line-height:150%;font-family:宋体'>统一信用代码：</span></p><p style='margin-bottom:0;margin-bottom:0;text-indent: 32px;line-height:150%'>    <span style='font-size:16px;line-height: 150%;background:yellow;background:yellow'>3.</span><span style='font-size:16px;line-height:150%;font-family:宋体;background:yellow;background:yellow'>住所：</span></p><p style='margin-bottom:0;margin-bottom:0;text-indent: 32px;line-height:150%'>    <span style='font-size:16px;line-height: 150%;background:yellow;background:yellow'>4.</span><span style='font-size:16px;line-height:150%;font-family:宋体;background:yellow;background:yellow'>法定代表人：</span></p><p style='margin-bottom:0;margin-bottom:0;text-indent: 32px;line-height:150%'>    <span style='font-size:16px;line-height: 150%;background:yellow;background:yellow'>5.</span><span style='font-size:16px;line-height:150%;font-family:宋体;background:yellow;background:yellow'>注册资本：</span></p><p>    <span style='font-size:16px;font-family:&#39;Times New Roman&#39;,serif;background:yellow;background:yellow'>&nbsp; &nbsp; &nbsp; &nbsp; 6.</span><span style='font-size:16px;font-family:宋体;background:yellow;background:yellow'>主要经营范围：</span></p><p>    <br/></p>";
//			XWPFDocument wordDoc = new XWPFDocument();
//			HtmlToWordUtil.createHeader(wordDoc, null, "小土科技", "正文");
//			HtmlToWordUtil.createFooter(wordDoc, null);
//			HtmlToWordUtil.addCustomHeadingStyle(wordDoc, "标题 1", 1, "黑体", "30");
//			HtmlToWordUtil.addCustomHeadingStyle(wordDoc, "标题 2", 2, "黑体", "24");
//			HtmlToWordUtil.htmlToWord(wordDoc, "", htmlStr);
//			FileOutputStream fos = new FileOutputStream("d:\\案件报告.docx");
//			wordDoc.write(fos);
//			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * html转成word
	 * @param wordDoc
	 * @param htmlStr
	 * @throws Exception
	 */
	public void htmlToWord(XWPFDocument wordDoc, String authName, String htmlStr) throws Exception {
		currentAuthName = authName;
		if(holdStyleTitleList.contains(authName)) {
			this.isHoldStyle = true;
		} else {
			this.isHoldStyle = false;
		}
		if(authName.equals("声明")) {
			this.line = 1.25;
		}
		//将红色字体的【】内容删掉
		htmlStr = htmlStr.replaceAll("<span\\s[^>]*style=\"(([^>]*[^a-zA-Z0-9-_]color)|(color))\\s*:\\s*((red)|(rgb\\(255,\\s*0,\\s*0\\)))[^>]*\">(((【[^】]*】)+)|((<span\\s[^>]*>【[^】]*】</span>)+)|(<span\\s[^>]*>(【[^】]*】)+</span>))</span>", "");
				
		if(!htmlStr.startsWith("<html>")) {
			htmlStr = "<html><body>" + htmlStr + "</body><html>";
		}
		org.jsoup.nodes.Document doc = Jsoup.parse(htmlStr, "utf-8");
		//去掉最开始、最后的空行
		Elements pEles = doc.getElementsByTag("p");
		for(int i = pEles.size() - 1; i >= 0; i--) {
			Element pEle = pEles.get(i);
			String text = pEle.text();
			if(StringUtils.isNotBlank(text)) {
				text = text.replace("&nbsp;", "");
				text = text.replace(" ", "");
			}
			if(StringUtils.isBlank(text)){
				pEle.remove();
			} else {
				break;
			}
		}
		pEles = doc.getElementsByTag("p");
		for(int i = 0; i < pEles.size(); i++) {
			Element pEle = pEles.get(i);
			String text = pEle.text();
			if(StringUtils.isNotBlank(text)) {
				text = text.replace("&nbsp;", "");
				text = text.replace(" ", "");
			}
			if(StringUtils.isBlank(text)){
				pEle.remove();
			} else {
				break;
			}
		}
		Elements eles = doc.getElementsByTag("body");
		List<Node> child = eles.get(0).childNodes();
		Elements allEles = eles.get(0).select("> *");
		if(child != null && child.size() > 0) {
			try {
				createWord(wordDoc, null, child, allEles);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 递归解析html创建word
	 * @param doc
	 * @param para
	 * @param nodes
	 * @param eles
	 * @throws Exception
	 */
	public void createWord(XWPFDocument doc, XWPFParagraph para, List<Node> nodes, Elements eles) throws Exception {
		int index = 0;
		for(int i = 0; i < nodes.size(); i++) {
			Node node = nodes.get(i);
			String nodeName = node.nodeName().toLowerCase();
			if(nodeName.equals("#text")) {
				if(para == null) {
					para = createPara(doc);
				}
				textToWord(para, node, "宋体", COMMON_FONTSIZE);
			} else if (nodeName.equals("img")) {
				try {
					if(para == null) {
						para = createPara(doc);
					}
					imgToWord(para, eles.get(index));
				} catch (Exception e) {
				}				
				index++;
			} else if (nodeName.equals("table")){
				tableToWord(doc, eles.get(index));
				index++;
			} else {
				if(nodeName.equals("ol")) {//自动编号项目
					String styleAttr = node.attr("style");
					listStyleType = getStyleAttrValue(styleAttr, "list-style-type");
					if(StringUtils.isNotBlank(listStyleType)) {
						switch(listStyleType) {
							case "decimal"://1.2.3.
								numId = createNumStyle(doc, "%1.", STNumberFormat.DECIMAL);
								break;
							case "lower-alpha"://a.b.c.
								numId = createNumStyle(doc, "%1.", STNumberFormat.LOWER_LETTER);
								break;
							case "upper-alpha"://A.B.C.
								numId = createNumStyle(doc, "%1.", STNumberFormat.UPPER_LETTER);
								break;
							case "lower-roman"://i.ii.iii.
								numId = createNumStyle(doc, "%1.", STNumberFormat.LOWER_ROMAN);
								break;
							case "upper-roman"://I.II.III.
								numId = createNumStyle(doc, "%1.", STNumberFormat.UPPER_ROMAN);
								break;
							case "circle"://空心圆
//								numId = createNumStyle(doc, "", STNumberFormat.CHINESE_COUNTING_THOUSAND);
								break;
							case "disc"://实心圆
								numId = createNumStyle(doc, "", STNumberFormat.BULLET);
								break;
							case "square"://小方块
//								numId = createNumStyle(doc, "", STNumberFormat.);
								break;
						}
					}
				} else if(nodeName.equals("p") || (nodeName.startsWith("h") && nodeName.length() == 2)) {
					String styleAttr = node.attr("style");
					String display = getStyleAttrValue(styleAttr, "display");
					if(StringUtils.isNotBlank(display) && display.equals("none")) {//隐藏段落不解析不显示
						index++;
						continue;
					}
					if(para != null) {
						if(StringUtils.isBlank(para.getText().trim())) {
							setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
				                    (int)(line * 240) + "", STLineSpacingRule.Enum.forString("auto"));
						}
					}
					para = doc.createParagraph();
					
					String beforeLines = "0";
					
					//表格后面段落设置段前0.5行
					if(i != 0 && nodes.get(i - 1).nodeName().equals("table")) {
						beforeLines = "50";
					}
					
					Element element = eles.get(index);
					if(element.hasText() && para.getIndentationFirstLine() <= 0 && !isHoldStyle) {
//						para.setIndentationFirstLine(480); //首行缩进：567==1厘米  32px--2个字符--200--480<w:ind w:firstLineChars="200" w:firstLine="480" />
						setParagraphFirstLine(para, 2);//首行缩进，2字符
					}
					//设置段落样式
					if(!isHoldStyle) {
						setParagraphSpacingInfo(para, true, "0", "0", true, beforeLines, "0", true,  
								 (int)(line * 240) + "", STLineSpacingRule.Enum.forString("auto"));
					} else {
						//设置缩进
						String textIndent = getStyleAttrValue(styleAttr, "text-indent");
						if(StringUtils.isNotBlank(textIndent)) {
							if(textIndent.indexOf("px") >= 0) {
								double textIndentNum = Integer.parseInt(textIndent.replace("px", ""));
//								para.setIndentationFirstLine(15 * textIndentNum); //首行缩进：567==1厘米
								setParagraphFirstLine(para, textIndentNum / 16);//首行缩进
							} else if(textIndent.indexOf("em") >= 0){
								double textIndentNum = Integer.parseInt(textIndent.replace("em", ""));
//								para.setIndentationFirstLine(15 * textIndentNum); //首行缩进：567==1厘米
								setParagraphFirstLine(para, textIndentNum);//首行缩进
							}
						}
						//设置行间距
						String lineHeight = getStyleAttrValue(styleAttr, "line-height");
						if(StringUtils.isNotBlank(lineHeight) && lineHeight.indexOf("%") >= 0) {
							lineHeight = lineHeight.replace("%", "");
							double num = Double.valueOf(lineHeight) / 100;
							setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
								(int) (num * 240) + "", STLineSpacingRule.Enum.forString("auto"));
						} else {//单倍行距
							setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
				                    "240", STLineSpacingRule.Enum.forString("auto"));
						}
						if(currentAuthName.equals("委托人信息")) {
							setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
									 (int)(line * 240) + "", STLineSpacingRule.Enum.forString("auto"));
						}
					}
					//设置段落居左、居中、居右显示
					String textAlign = getStyleAttrValue(styleAttr, "text-align");
					if(StringUtils.isNotBlank(textAlign)) {
						if(textAlign.equals("center")) {
							setParagraphAlignInfo(para, ParagraphAlignment.CENTER, TextAlignment.CENTER);
						} else if(textAlign.equals("left")) {
							setParagraphAlignInfo(para, ParagraphAlignment.LEFT, TextAlignment.CENTER);
						} else if(textAlign.equals("right")) {
							setParagraphAlignInfo(para, ParagraphAlignment.RIGHT, TextAlignment.CENTER);
						}
					}
//					else {
//						setParagraphAlignInfo(para, ParagraphAlignment.LEFT, TextAlignment.CENTER);
//					}
					boolean isOLP = false;
					if(numId != null) {
						Node pNode = node.parent();
						if(pNode != null && pNode.nodeName().equals("li")) {
							Node ppNode = pNode.parent();
							if(ppNode != null && ppNode.nodeName().equals("ol")) {
								String pstyleAttr = ppNode.attr("style");
								String pListStyleType = getStyleAttrValue(pstyleAttr, "list-style-type");
								if(pListStyleType.equals(listStyleType)) {
									para.setNumID(numId);
									isOLP = true;
								}
							}
						}
					}
					if(!isOLP) {
						listStyleType = "";
						numId = null;
					}
				}
				List<Node> child = node.childNodes();
				Elements allEles = eles.get(index).select("> *");
				if(child != null && child.size() > 0) {
					createWord(doc, para, child, allEles);
				}
				index++;
			}
		}
	}
	
	public XWPFParagraph createPara(XWPFDocument doc) {
		XWPFParagraph para = doc.createParagraph();
		setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
				 (int)(line * 240) + "", STLineSpacingRule.Enum.forString("auto"));
		return para;
	}
	
//	public void createWord(XWPFDocument doc, Elements eles) throws Exception {
//		for(Element ele : eles) {
//			if(ele.nodeName().equals("table")) {
//				tableToWord(doc, ele);
//			} else {
//				Elements allEles = ele.select("> *");
//				if(allEles != null && allEles.size() > 0) {
//					createWord(doc, allEles);
//				} else {
//					if(ele.nodeName().equals("img")) {
//						imgToWord(doc, ele);
//					} else {
//						textToWord(doc, ele);
//					}
//				}
//			}
//		}
//	}
	
	/**
	 * 表格中插入文本
	 * @param para
	 * @param ele
	 */
	public List<XWPFRun> textToWord(XWPFParagraph para, Node node, String fontFamily, String fontSize) {
		List<XWPFRun> XWPFRunList = new ArrayList<XWPFRun>();
		String text = node.toString();
		if(StringUtils.isNotBlank(text)) {
			text = text.replace("&nbsp;", " ");
			text = text.replace("&times;", "X");
			text = text.replace("（", "(");
			text = text.replace("）", ")");
		}
		String newText = text.trim();
		//处理数字、英文 字体
		Matcher m = Pattern.compile("[0-9.]+|[a-zA-Z]+|[\u4e00-\u9fa5]+|\\pP+|\\pS+|\\s+|\t+|　+").matcher(newText);
		List<String> partList = new ArrayList<String>();
		while (m.find()) {
			String partText = m.group();
			partList.add(partText);
		}
		List<String> newPartList = new ArrayList<String>();
		for(String part : partList) {
			if(newText.indexOf(part) != 0) {
				newPartList.add(newText.substring(0, newText.indexOf(part)));
			}
			newPartList.add(part);
			newText = newText.substring(newText.indexOf(part) + part.length());
		}
		if(StringUtils.isNotBlank(newText)) {
			newPartList.add(newText);
		}
		for(String part : newPartList) {
			XWPFRun run = para.createRun();
			String newFontFamily = fontFamily;
			if(ValidateUtil.isNumber(part) || ValidateUtil.isEnglish(part)) {
				newFontFamily = "Times New Roman";
			}
			setParagraphTextStyleInfo(run, newFontFamily, fontSize);
			getTextStyle(run, node, text, newFontFamily, fontSize);
			run.setText(part);
			XWPFRunList.add(run);
		}
		
		return XWPFRunList;
	}
	
	/**
	 * 获取文本格式
	 * @param run
	 * @param node
	 * @param text
	 */
	public void getTextStyle(XWPFRun run, Node node, String text, String fontFamily, String fontSize) {
		Node pNode = node.parent();
		if(pNode == null) {
			return;
		}
		Element pElement = (Element) pNode;
		String pText = pElement.text();
		pText = pText.replace("（", "(");
		pText = pText.replace("）", ")");
		if(StringUtils.isNotBlank(text) && !pText.equals(text)) {
			return;
		}
		switch(pNode.nodeName().toLowerCase()) {
			case "strong":
				run.setBold(true);
				break;
			case "sup":
				run.setSubscript(VerticalAlign.SUPERSCRIPT);
				break;
			case "sub":
				run.setSubscript(VerticalAlign.SUBSCRIPT);
				break;
			default:
				break;
		}
		if(isHoldStyle && pNode.nodeName().equals("span")) {
			String styleAttr = pNode.attr("style");
			String fontSizeStr = getStyleAttrValue(styleAttr, "font-size");//1px= 0.75pt,不进行四舍五入
			String fontFamilyStr = getStyleAttrValue(styleAttr, "font-family");
			if(StringUtils.isNotBlank(fontSizeStr)) {
				try {
					if(fontSizeStr.contains("px")) {
						fontSize = ((int) (Integer.parseInt(fontSizeStr.replace("px", "")) * 0.75 * 2)) + "";
					} else {
						fontSize = ((int) (Integer.parseInt(fontSizeStr.replace("pt", "")) * 2)) + "";
					}
				} catch (Exception e) {//如果转整形异常，使用默认字体大小
					
				}
			}
			if(StringUtils.isNotBlank(fontFamilyStr) && !fontFamily.equals("Times New Roman")) {
				fontFamily = fontFamilyStr;
			}
			setParagraphTextStyleInfo(run, fontFamily, fontSize);			
		}
		getTextStyle(run, pNode, text, fontFamily, fontSize);
	}
	
//	public void textToWord(XWPFParagraph para, Element ele) {
//		XWPFRun run = para.createRun();
//		setParagraphTextStyleInfo(run, "宋体", COMMON_FONTSIZE, false);
////		XWPFParagraph para = doc.createParagraph();
//		run.setText(ele.text().replaceAll("<.*>.*</[\\w-\\W-]*>", ""));
//	}
	
	/**
	 * word中插入图片
	 * @param para
	 * @param ele
	 * @throws Exception
	 */
	public void imgToWord(XWPFParagraph para, Element ele) throws Exception {
//		XWPFParagraph para = doc.createParagraph();
		XWPFRun run = para.createRun();
//		run.addBreak(BreakType.TEXT_WRAPPING);
		HttpURLConnection httpUrl = null;
		InputStream input = null;
		try {
			String imageSrc = ele.attr("src");
			String fileName = imageSrc.substring(imageSrc.lastIndexOf("/") + 1);
			
			String styleAttr = ele.attr("style"); // 样式
			// 高度
			String imagHeightStr = ele.attr("height");
			if (StringUtils.isEmpty(imagHeightStr)) {
				imagHeightStr = getStyleAttrValue(styleAttr, "height");
			}
			// 宽度
			String imagWidthStr = ele.attr("width");
			if (StringUtils.isEmpty(imagHeightStr)) {
				imagHeightStr = getStyleAttrValue(styleAttr, "width");
			}

			imagHeightStr = imagHeightStr.replace("px", "").replace("pt", "");
			imagWidthStr = imagWidthStr.replace("px", "").replace("pt", "");
			if (StringUtils.isEmpty(imagHeightStr)) {
				// 去得到默认的文件高度
				imagHeightStr = "0";
			}
			if (StringUtils.isEmpty(imagWidthStr)) {
				imagWidthStr = "0";
			}
			int imageHeight = Integer.parseInt(imagHeightStr);
			int imageWidth = Integer.parseInt(imagWidthStr);
			
			if(imageHeight == 0 || imageWidth == 0) {
				URL url = new URL(imageSrc);
				httpUrl = (HttpURLConnection) url.openConnection();
				httpUrl.connect();
				input = httpUrl.getInputStream();
				BufferedImage sourceImg = ImageIO.read(input);
				if (imageHeight == 0) {
					imageHeight = sourceImg.getHeight();
				}
				if (imageWidth == 0) {
					imageWidth = sourceImg.getWidth();
				}
				httpUrl.disconnect();
			}
			if(imageWidth>555) {
				imageHeight = imageHeight * 555 / imageWidth;
				imageWidth = 555;
			}
			
			URL url = new URL(imageSrc);
			httpUrl = (HttpURLConnection) url.openConnection();
			httpUrl.connect();
			input = httpUrl.getInputStream();
//			run.addPicture(input, Document.PICTURE_TYPE_PNG, fileName, Units.toEMU(imageWidth),
//					Units.toEMU(imageHeight));
			run.addPicture(input, Document.PICTURE_TYPE_PNG, fileName, EMU * imageWidth,
					EMU * imageHeight);
		} catch (Exception e) {
			throw e;
		} finally {
			if(input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(httpUrl != null) {
				httpUrl.disconnect();
			}
		}
	}
	/**
	 * 获取样式
	 * @param style
	 * @param attributeKey
	 * @return
	 */
	private String getStyleAttrValue(String style, String attributeKey) {
		if (StringUtils.isEmpty(style)) {
			return "";
		}

		// 以";"分割
		String[] styleAttrValues = style.split(";");
		for (String item : styleAttrValues) {
			// 在以 ":"分割
			String[] keyValuePairs = item.split(":", -1);
			if (attributeKey.equals(keyValuePairs[0].trim())) {
				return keyValuePairs[1].trim();
			}
		}

		return "";
	}

	/**
	 * html表格转成word表格
	 * @param doc
	 * @param tableEle
	 * @throws Exception
	 */
	public void tableToWord(XWPFDocument doc, Element tableEle) throws Exception {
		Elements trs = tableEle.getElementsByTag("tr");
		int rowSize = trs.size();
		int columnSize = 0;
		for(Element tr : trs) {
			int trColumnSize = 0;
			for(Element td : tr.select("> *")) {
				if (StringUtils.isNotBlank(td.attr("colspan"))) {
					trColumnSize += Integer.parseInt(td.attr("colspan"));
				} else {
					trColumnSize++;
				}
			}
			if(columnSize < trColumnSize) {
				columnSize = trColumnSize;
			}
		}
		
//		for(Element tr : trs) {
//			Elements tds = tr.select("> *");
//			int newColumnSize = 0;
//			for(Element td : tds) {
//				if (StringUtils.isNotBlank(td.attr("colspan"))) {
//					newColumnSize += Integer.parseInt(td.attr("colspan"));
//				} else {
//					newColumnSize++;
//				}
//			}
//			if(columnSize < newColumnSize) {
//				columnSize = newColumnSize;
//			}
//		}
		List<TD> dataList = new ArrayList<TD>();
		for(int i = 0; i < trs.size(); i++) {
			Element tr = trs.get(i);
			
			boolean isHead = false;
			if(tr.parent().nodeName().equals("thead")) {
				isHead = true;
			}
			//获取td
			Elements tds = tr.select("> *");
			for(int j = 0; j < tds.size(); j++) {
				Element e = tds.get(j);
				TD td = new TD();
				String styleAttr = e.attr("style");
				if (StringUtils.isNotBlank(e.attr("colspan"))) {
					td.setColspan(Integer.valueOf(e.attr("colspan").trim()));
				}
				if (StringUtils.isNotBlank(e.attr("rowspan"))) {
					td.setRowspan(Integer.valueOf(e.attr("rowspan").trim()));
				}
				if (StringUtils.isNotBlank(e.attr("width")) && !e.attr("width").equals("undefined")) {
					String width = e.attr("width").replace("px", "").replace("pt", "").trim();
					if(NumberUtil.isNumeric(width)) {
						td.setWidth(new Double(width).intValue());
					}
				} else {
					String width = getStyleAttrValue(styleAttr, "width");
					if(StringUtils.isNotBlank(width) && !width.equals("undefined")) {
						String newWidth = width.replace("px", "").replace("pt", "");
						td.setWidth(new Double(newWidth).intValue());
					}
				}
				if (StringUtils.isNotBlank(e.attr("align"))) {
					td.setAlign(e.attr("align").trim());
				} else {
					String textAlign = getStyleAttrValue(styleAttr, "text-align");
					if(StringUtils.isNotBlank(textAlign)) {
						td.setAlign(textAlign);
					}
				}
				//获取单元格边线
				String border = getStyleAttrValue(styleAttr, "border");
				if(StringUtils.isBlank(border)) {
					border = getStyleAttrValue(styleAttr, "border-style");
				}
				if(StringUtils.isNotBlank(border)) {
					td.setBorderLeft(border);
					td.setBorderTop(border);
					td.setBorderRight(border);
					td.setBorderBottom(border);
				}
				String borderLeft = getStyleAttrValue(styleAttr, "border-left");
				if(StringUtils.isNotBlank(borderLeft)) {
					td.setBorderLeft(borderLeft);
				}
				String borderTop = getStyleAttrValue(styleAttr, "border-top");
				if(StringUtils.isNotBlank(borderTop)) {
					td.setBorderTop(borderTop);
				}
				String borderRight = getStyleAttrValue(styleAttr, "border-right");
				if(StringUtils.isNotBlank(borderRight)) {
					td.setBorderRight(borderRight);
				}
				String borderBottom = getStyleAttrValue(styleAttr, "border-bottom");
				if(StringUtils.isNotBlank(borderBottom)) {
					td.setBorderBottom(borderBottom);
				}
				td.setStyle(styleAttr);
				
				td.setContent(e.html());//e.text();
				if(e.nodeName().equals("td")) {
					td.setX(HorizontalDeduction_td(e));// 步骤1：横向推导，但这个坐标并不是最终坐标，需要进行纵向推导
				} else {
					td.setX(HorizontalDeduction_th(e));
				}
				td.setY(i);// y坐标很简单，就是tr的值
				td.setIsHead(isHead);
				dataList.add(td);
			}
		}
		// 步骤2：纵向推导
		dataList = verticalDeduction(dataList);
		
		buildWordTable(doc, dataList, rowSize, columnSize);
	}
		
	/**
	 * 构建word表格
	 * @param doc
	 * @param dataList
	 * @param rowSize
	 * @param columnSize
	 * @throws Exception
	 */
	public void buildWordTable(XWPFDocument doc, List<TD> dataList, int rowSize, int columnSize) throws Exception {
		XWPFTable table = doc.createTable(rowSize, columnSize);
//		CTTblPr tablePr = table.getCTTbl().addNewTblPr();
//		CTTblWidth width = tablePr.addNewTblW();
//		width.setW(BigInteger.valueOf(8000));
		//表格宽度
		setTableWidth(table, "8200");
		for (int i = 0; i < dataList.size(); i++) {			
			TD td = dataList.get(i);
			XWPFTableRow row = table.getRow(td.getY());
//				row.setHeight(360);
			CTRow ctRow = row.getCtRow();
			CTTrPr ctTrPr = ctRow.isSetTrPr() ? ctRow.getTrPr() : ctRow.addNewTrPr();
			//设置标题行，在各页顶端以标题行形式出现，冻结标题行
			if(td.getIsHead()) {
				List<CTOnOff> tblHeaderList = ctTrPr.getTblHeaderList();
				if(tblHeaderList == null || tblHeaderList.size() == 0) {
					ctTrPr.addNewTblHeader();
				}
			}
			//设置行高，垂直位置居中
			CTHeight ctHeight = ctTrPr.addNewTrHeight();
			ctHeight.setHRule(STHeightRule.AT_LEAST); //设置行高最小值
			ctHeight.setVal(BigInteger.valueOf(360));
			ctTrPr.addNewJc().setVal(STJc.CENTER);
			
			XWPFTableCell cell = row.getCell(td.getX());
			
			String content = td.getContent();
			org.jsoup.nodes.Document tdDoc = Jsoup.parse("<html><body>" + content + "</body></html>", "utf-8");
			Elements allEles = tdDoc.getElementsByTag("body");
			List<Node> child = allEles.get(0).childNodes();
			Elements eles = allEles.get(0).select("> *");
			if(child != null && child.size() > 0) {
				List<XWPFParagraph> paras = cell.getParagraphs();
				XWPFParagraph para = null;
				if(paras != null && paras.size() > 0) {
					para = paras.get(0);
					setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
		                    "240", STLineSpacingRule.Enum.forString("auto"));
				}
				createTdPara(cell, para, 0, child, eles, td);
				
				//设置单元格样式
				setCellTextStyle(cell, td);
				//加粗
				String style = td.getStyle();
				String fontWeight = getStyleAttrValue(style, "font-weight");
				if(StringUtils.isNotBlank(fontWeight) && Integer.parseInt(fontWeight) > 400) {
					paras = cell.getParagraphs();
					for(XWPFParagraph one : paras) {
						List<XWPFRun> runs = one.getRuns();
						for(XWPFRun run : runs) {
							run.setBold(true);
						}
					}
				}
			}
			// 合并列
			for(int j = 0; j < td.getRowspan(); j++) {
				mergeCellsHorizontal(table, td.getY() + j, td.getX(), td.getX() + (td.getColspan() - 1));
			}
			// 合并行
			for(int j = 0; j < td.getColspan() && j < columnSize; j++) {
				mergeCellsVertically(table, td.getX() + j, td.getY(), td.getY() + (td.getRowspan() - 1));
			}
		}
		//去掉左右边线
		for(int i = 0; i < rowSize; i++) {
			XWPFTableRow row = table.getRow(i);
			boolean isHMerge = false;
			Integer cellIndex = null;
			for(int j = 0; j < columnSize; j++) {
				XWPFTableCell cell = row.getCell(j);
				CTTc cttc = cell.getCTTc();
		        CTTcPr ctPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
		        if(ctPr.isSetHMerge() && ctPr.getHMerge().getVal().equals(STMerge.RESTART)) {
		        	isHMerge = true;
	        		cellIndex = j;
	        	}
		        CTTcBorders border = ctPr.isSetTcBorders() ? ctPr.getTcBorders() : ctPr.addNewTcBorders();
		        
		        if(j == 0) {
			        CTBorder bLeft = border.getLeft() == null ? border.addNewLeft() : border.getLeft();
			        bLeft.setVal(STBorder.NIL);
		        }
		        if(j == columnSize - 1) {
		        	if(isHMerge) {
		        		cell = row.getCell(cellIndex);
		        		cttc = cell.getCTTc();
		        		ctPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
				        border = ctPr.isSetTcBorders() ? ctPr.getTcBorders() : ctPr.addNewTcBorders();
		        	}
					CTBorder bRight = border.getRight() == null ? border.addNewRight() : border.getRight();
					bRight.setVal(STBorder.NIL);
		        }
			}
		}
	}

	/**
	 * 设置表格宽度、表格居中
	 * @param table
	 * @param width
	 */
	public void setTableWidth(XWPFTable table, String width) {  
        CTTbl ttbl = table.getCTTbl();  
        CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl  
                .getTblPr();  
        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr  
                .addNewTblW();  
        CTJc cTJc = tblPr.addNewJc();  
        cTJc.setVal(STJc.CENTER);  
        tblWidth.setW(new BigInteger(width));
        tblWidth.setType(STTblWidth.DXA);
        table.setCellMargins(20, 20, 20, 20);
    }
	
	/**
	 * 设置单元格内容样式
	 * @param cell 单元格
	 * @param width 宽度
	 * @param stVert 垂直位置
	 * @param stJc 横向位置
	 */
	public void setCellTextStyle(XWPFTableCell cell, TD td) {  
        CTTc cttc = cell.getCTTc();
        CTTcPr ctPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr(); 
//      CTShd ctshd = ctPr.isSetShd() ? ctPr.getShd() : ctPr.addNewShd();
        //宽度
        int width = td.getWidth();
        if(width != 0) {
            ctPr.addNewTcW().setW(BigInteger.valueOf(width));
        } else {
        	ctPr.addNewTcW().setType(STTblWidth.AUTO);
        }
        ctPr.addNewVMerge().setVal(STMerge.RESTART);
        ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
        //位置
        CTPPr pPr = cttc.getPList().get(0).isSetPPr() ?  cttc.getPList().get(0).getPPr(): cttc.getPList().get(0).addNewPPr();
        String align = td.getAlign();
        if(StringUtils.isNotBlank(align)) {
        	if(align.equals("center")) {
        		pPr.addNewJc().setVal(STJc.CENTER);
        	} else if(align.equals("right")) {
        		pPr.addNewJc().setVal(STJc.RIGHT);
        	}
        }
//        String style = td.getStyle();
//        if(StringUtils.isNotBlank(style)) {
//        	String fontWeight = getStyleAttrValue(style, "font-weight");
//        	if(StringUtils.isNotBlank(fontWeight) && Integer.parseInt(fontWeight) > 400) {
//        		pPr.addNewRPr().addNewB();
//        	}
//        }
		//设置单元格边线
        CTTcBorders border = ctPr.isSetTcBorders() ? ctPr.getTcBorders() : ctPr.addNewTcBorders();
		CTBorder bLeft = border.getLeft() == null ? border.addNewLeft() : border.getLeft();
		if(StringUtils.isNotBlank(td.getBorderLeft()) && td.getBorderLeft().trim().equals("none")) {
			bLeft.setVal(STBorder.NIL);
		} else {
			bLeft.setVal(STBorder.SINGLE);
			bLeft.setSz(BigInteger.valueOf(4));
		}
		CTBorder bTop = border.getTop() == null ? border.addNewTop() : border.getTop();
		if(StringUtils.isNotBlank(td.getBorderTop()) && td.getBorderTop().trim().equals("none")) {
			bTop.setVal(STBorder.NIL);
		} else {
			bTop.setVal(STBorder.SINGLE);
			bTop.setSz(BigInteger.valueOf(4));
		}
		CTBorder bRight = border.getRight() == null ? border.addNewRight() : border.getRight();
		if(StringUtils.isNotBlank(td.getBorderRight()) && td.getBorderRight().trim().equals("none")) {
			bRight.setVal(STBorder.NIL);
		} else {
			bRight.setVal(STBorder.SINGLE);
			bRight.setSz(BigInteger.valueOf(4));
		}
		CTBorder bBottom = border.getBottom() == null ? border.addNewBottom() : border.getBottom();
		if(StringUtils.isNotBlank(td.getBorderBottom()) && td.getBorderBottom().trim().equals("none")) {
			bBottom.setVal(STBorder.NIL);
		} else {
			bBottom.setVal(STBorder.SINGLE);
			bBottom.setSz(BigInteger.valueOf(4));
		}
    }
	
	/**
	 * 递归生成word单元格内容
	 * @param cell
	 * @param para
	 * @param paraIndex
	 * @param nodes
	 * @param eles
	 * @throws Exception
	 */
	public void createTdPara(XWPFTableCell cell, XWPFParagraph para, int paraIndex, List<Node> nodes, Elements eles, TD td) throws Exception {
		int index = 0;
		for(Node node : nodes) {
			if(node.nodeName().equals("#text")) {
				if(para == null) {
					para = cell.addParagraph();
					setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
		                    "240", STLineSpacingRule.Enum.forString("auto"));
				}
				String fontSize = COMMON_FONTSIZE_TATBLE_CONTENT;
				if(td.getIsHead()) {
					fontSize = COMMON_FONTSIZE_TATBLE_TITLE;
				}
				List<XWPFRun> run = textToWord(para, node, "宋体", fontSize);
				
				//处理显示表格中空格，解决asposeword转化后空格不显示问题
				String text = node.toString();
				if(StringUtils.isNotBlank(text)) {
					text = text.replace("\n", "");
					text = text.replace("&nbsp;", " ");
				}
				
				if(text.startsWith(" ") && StringUtils.isNotBlank(text.trim())) {
					run.get(0).getCTR().getTList().get(0).setSpace(SpaceAttribute.Space.PRESERVE);
				}
//				run.setFontFamily("Times New Roman");
				//处理数字字体Times New Roman
//				if(StringUtils.isNotBlank(text.trim())) {
//					if(ValidateUtil.isNumber(text.trim())) {
//						run.setFontFamily("Times New Roman");
//					}
//				}
			} else if (node.nodeName().equals("img")) {
				try {
					if(para == null) {
						para = cell.addParagraph();
						setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
			                    "240", STLineSpacingRule.Enum.forString("auto"));
					}
					imgToWord(para, eles.get(index));
				} catch (Exception e) {
				}
				index++;
			} else {
				if(node.nodeName().equals("p")) {
					if(paraIndex != 0) {
						para = cell.addParagraph();
						setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
			                    "240", STLineSpacingRule.Enum.forString("auto"));
					}
					//设置段落居左、居中、居右显示
					String styleAttr = node.attr("style");
					String textAlign = getStyleAttrValue(styleAttr, "text-align");
					if(StringUtils.isNotBlank(textAlign)) {
						if(textAlign.equals("center")) {
							setParagraphAlignInfo(para, ParagraphAlignment.CENTER, TextAlignment.CENTER);
						} else if(textAlign.equals("left")) {
							setParagraphAlignInfo(para, ParagraphAlignment.LEFT, TextAlignment.CENTER);
						} else if(textAlign.equals("right")) {
							setParagraphAlignInfo(para, ParagraphAlignment.RIGHT, TextAlignment.CENTER);
						}
					}
//					else {
//						setParagraphAlignInfo(para, ParagraphAlignment.LEFT, TextAlignment.CENTER);
//					}
					paraIndex++;
				}
				List<Node> child = node.childNodes();
				Elements allEles = eles.get(index).select("> *");
				if(child != null && child.size() > 0) {
					createTdPara(cell, para, paraIndex, child, allEles, td);
				}
				index++;
			}
		}
	}
	
	/**
	 * @Title : HorizontalDeduction
	 * @Description : 使用递归，进行横坐标的第一步推导，横向推导，同时删除多余的非td元素
	 * @param e
	 * @return
	 */
	private int HorizontalDeduction_td(Element e) {
		Element preElement = e.previousElementSibling();
		if (preElement != null) {
			if (!preElement.tagName().equals("td")) {// 表示td的上一个兄弟节点不是td，则删除这个多余的元素
				preElement.remove();
			} else {
				int nColSpan = 1;// 默认为1
				if (StringUtils.isNotBlank(preElement.attr("colspan"))) {
					nColSpan = Integer.valueOf(preElement.attr("colspan").trim());// 前一个元素的列合并情况
				}
				return HorizontalDeduction_td(preElement) + nColSpan;
			}
		}
		return 0;
	}
	
	/**
	 * @Title : HorizontalDeduction
	 * @Description : 使用递归，进行横坐标的第一步推导，横向推导，同时删除多余的非td元素
	 * @param e
	 * @return
	 */
	private int HorizontalDeduction_th(Element e) {
		Element preElement = e.previousElementSibling();
		if (preElement != null) {
			if (!preElement.tagName().equals("th")) {// 表示td的上一个兄弟节点不是td，则删除这个多余的元素
				preElement.remove();
			} else {
				int nColSpan = 1;// 默认为1
				if (StringUtils.isNotBlank(preElement.attr("colspan"))) {
					nColSpan = Integer.valueOf(preElement.attr("colspan").trim());// 前一个元素的列合并情况
				}
				return HorizontalDeduction_th(preElement) + nColSpan;
			}
		}
		return 0;
	}
	
	/**
	 * @Title : verticalDeduction
	 * @Description : 纵向推导
	 * @param headerList
	 * @return
	 */
	private List<TD> verticalDeduction(List<TD> headerList) {
		int headerSize = headerList.size();
		for (int i = 0; i < headerSize; i++) {
			TD tdA = headerList.get(i);
			boolean flag = true;
			while (flag) {// 不断排列当前节点的位置，直到它的位置绝对正确
				flag = false;// 不需要移位
				for (int j = i - 1; j >= 0; j--) {// 找到之前与td的横坐标相等的值
					TD tdB = headerList.get(j);
					if (tdA.getX() == tdB.getX()) {// A找到与其X坐标相等的B
						if (tdB.getRowspan() > tdA.getY() - tdB.getY()) {// 如果B单元格“挡住”了A单元格，才进行移位操作。即：只有B占的行数大于或等于A、B之间的距离，那么B才会挡住A
							flag = true;// 如果存在移位单元格，则仍然需要重新判断当前的位置是否正确。需要移位
							tdA.setX(tdA.getX() + tdB.getColspan());// A的X坐标向后推B.colspan的位置
							int YA = tdA.getY();
							for (int m = i + 1; m < headerSize; m++) {// 同时，与A同处一tr但在其后边的td节点均应向后推B.colspan个位移
								TD td = headerList.get(m);
								if (td.getY() == YA) {
									td.setX(td.getX() + tdB.getColspan());
								}
							}
						}
					}
				}
			}
		}
		return headerList;
	}
	
	// word跨列合并单元格
	private void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {  
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {  
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);  
        	CTTc cttc = cell.getCTTc();
	        CTTcPr ctPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
	        CTHMerge ctHMerge = ctPr.isSetHMerge() ? ctPr.getHMerge() : ctPr.addNewHMerge();
            if ( cellIndex == fromCell ) {  
                // The first merged cell is set with RESTART merge value  
            	ctHMerge.setVal(STMerge.RESTART);  
            } else {  
                // Cells which join (merge) the first one, are set with CONTINUE  
            	ctHMerge.setVal(STMerge.CONTINUE);  
            }  
        }  
    }  
	// word跨行并单元格
	private void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {  
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {  
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);  
        	CTTc cttc = cell.getCTTc();
	        CTTcPr ctPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();
	        CTVMerge ctVMerge = ctPr.isSetVMerge() ? ctPr.getVMerge() : ctPr.addNewVMerge();
            if ( rowIndex == fromRow ) {  
                // The first merged cell is set with RESTART merge value  
            	ctVMerge.setVal(STMerge.RESTART);  
            } else {  
                // Cells which join (merge) the first one, are set with CONTINUE  
            	ctVMerge.setVal(STMerge.CONTINUE);  
            }  
        }  
    }
	
	/**
	 * 设置页面大小、页边距
	 * @param doc
	 */
	public static void setPageSize(XWPFDocument doc, CTSectPr sectPr) {
		CTDocument1 document = doc.getDocument();
		CTBody body = document.getBody();
		if(sectPr == null) {
			sectPr = body.getSectPr();
			if(sectPr == null) {
				sectPr = body.addNewSectPr();
			}
		}
		if(!sectPr.isSetPgSz()) {
			sectPr.addNewPgSz();
		}
		// 设置页面大小  当前A4大小
		CTPageSz pageSize = sectPr.getPgSz();
		pageSize.setW(BigInteger.valueOf(11907));
		pageSize.setH(BigInteger.valueOf(16840));
		pageSize.setOrient(STPageOrientation.PORTRAIT);
		CTPageMar pageMar = sectPr.getPgMar();
		if(pageMar == null) {
			pageMar = sectPr.addNewPgMar();
		}
		pageMar.setTop(BigInteger.valueOf(1440));
		pageMar.setRight(BigInteger.valueOf(1800));
		pageMar.setBottom(BigInteger.valueOf(1440));
		pageMar.setLeft(BigInteger.valueOf(1800));
		pageMar.setHeader(BigInteger.valueOf(851));
		pageMar.setFooter(BigInteger.valueOf(680));
		pageMar.setGutter(BigInteger.valueOf(0));
	}
	
	/**
	 * 创建页眉
	 * @param doc
	 * @param projectName 项目名称
	 * @param paraName 章节名
	 * @throws Exception
	 */
	public static void createHeader(XWPFDocument doc, CTSectPr sectPr, String projectName, String paraName)
			throws Exception {
		/*
		 * 对页眉段落作处理，使公司logo图片在页眉左边，公司全称在页眉右边
		 */
		CTDocument1 document = doc.getDocument();
		CTBody body = document.getBody();
		if(sectPr == null) {
			sectPr = body.getSectPr();
			if(sectPr == null) {
				sectPr = body.addNewSectPr();
			}
		}
		setPageSize(doc, sectPr);
		XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);
		XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
		
		CTSectPr bodySect = doc.getDocument().getBody().getSectPr();
		List<CTHdrFtrRef> hfRef = bodySect.getHeaderReferenceList();
		for(int i = 0; i < hfRef.size(); i++) {
			bodySect.removeHeaderReference(i);
		}		
		sectPr.addNewHeaderReference().setId(header.getPackageRelationship().getId());
		
		if(StringUtils.isBlank(projectName) && StringUtils.isBlank(paraName)) {
			return;
		}

		XWPFParagraph paragraph = header.getParagraphArray(0);
		paragraph.setAlignment(ParagraphAlignment.LEFT);
		paragraph.setBorderBottom(Borders.THICK);
		paragraph.getCTP().getPPr().getPBdr().getBottom().setSz(BigInteger.valueOf(6));//解决WPS边线不显示

		CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
		tabStop.setVal(STTabJc.RIGHT);
		int twipsPerInch = 1380;
		tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

		XWPFRun run = null;

		/*
		 * 添加字体页眉，项目名称，项目名称在左边
		 */
		if (StringUtils.isNotBlank(projectName)) {
			run = paragraph.createRun();
			run.setText(projectName);
			setXWPFRunStyle(run, "宋体", 9);
			run.addTab();
		}

		/*
		 * 章节标题在右边
		 */
		if (StringUtils.isNotBlank(paraName)) {
			run = paragraph.createRun();
			run.setText(paraName);
			setXWPFRunStyle(run, "宋体", 9);
		}
//		System.out.println(doc.getDocument().toString());
//		System.out.println("-----------------------------------------------------------");
	}

	/**
	 * 创建页脚
	 * @param doc
	 * @param sectPr 节
	 * @param isNull 是否空页脚
	 * @param isRenew 页码是否从1开始
	 * @throws Exception
	 */
	public static void createFooter(XWPFDocument doc, CTSectPr sectPr, boolean isNull, String pageNum)
			throws Exception {
		/*
		 * 生成页脚段落 给段落设置宽度为占满一行 为公司图标左对齐，页码右对齐创造条件
		 */
		CTDocument1 document = doc.getDocument();
		CTBody body = document.getBody();
		if(sectPr == null) {
			sectPr = body.getSectPr();
			if(sectPr == null) {
				sectPr = body.addNewSectPr();
			}
		}
		setPageSize(doc, sectPr);
		if(StringUtils.isNotBlank(pageNum)) {
			sectPr.addNewPgNumType().setStart(BigInteger.valueOf(Integer.parseInt(pageNum)));//页号重新从1开始
		}
		XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);
		XWPFFooter footer = headerFooterPolicy.createFooter(STHdrFtr.DEFAULT);
		
		CTSectPr bodySect = doc.getDocument().getBody().getSectPr();
		List<CTHdrFtrRef> hfRef = bodySect.getFooterReferenceList();
		for(int i = 0; i < hfRef.size(); i++) {
			bodySect.removeFooterReference(i);
		}
		
		sectPr.addNewFooterReference().setId(footer.getPackageRelationship().getId());	
		
		if(isNull) {
			return;
		}
		XWPFParagraph paragraph = footer.getParagraphArray(0);
		paragraph.setAlignment(ParagraphAlignment.LEFT);
		paragraph.setVerticalAlignment(TextAlignment.CENTER);
		paragraph.setBorderTop(Borders.THICK);
		paragraph.getCTP().getPPr().getPBdr().getTop().setSz(BigInteger.valueOf(6));//解决WPS边线不显示
		CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
		tabStop.setVal(STTabJc.RIGHT);
		int twipsPerInch = 1380;
		tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

		/*
		 * 给段落创建元素 设置元素字面为公司图标
		 */
		XWPFRun run = paragraph.createRun();
		InputStream is = HtmlToWordUtil.class.getResourceAsStream("/static/images/logo.png");

		XWPFPicture picture = run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, "logo.png",
				Units.toEMU(141), Units.toEMU(22));

		String blipID = "";
		for (XWPFPictureData picturedata : footer.getAllPackagePictures()) { // 这段必须有，不然打开的logo图片不显示
			if(StringUtils.isNotBlank(footer.getRelationId(picturedata))) {
				blipID = footer.getRelationId(picturedata);
			}
		}
		picture.getCTPicture().getBlipFill().getBlip().setEmbed(blipID);
		run.addTab();
		is.close();
		//
//		List<CTDrawing> drawingList = run.getCTR().getDrawingList();
//		CTDrawing drawing = null;
//		if(drawingList == null || drawingList.size() == 0) {
//			drawing = run.getCTR().addNewDrawing();
//		} else {
//			drawing = drawingList.get(0);
//		}

		/*
		 * 生成页码 页码右对齐
		 */

		run = paragraph.createRun();
		CTFldChar fldChar = run.getCTR().addNewFldChar();
		fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

		run = paragraph.createRun();
		CTText ctText = run.getCTR().addNewInstrText();
		ctText.setStringValue("PAGE  \\* MERGEFORMAT");
		fldChar = run.getCTR().addNewFldChar();
		fldChar.setFldCharType(STFldCharType.Enum.forString("separate"));
		ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
		setXWPFRunStyle(run, "宋体", 9);

		fldChar = run.getCTR().addNewFldChar();
		fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
	}

	/**
	 * 创建页脚，罗马编号，居中显示
	 * @param document
	 * @throws Exception
	 */
	public static void createFooterRoman(XWPFDocument doc, CTSectPr sectPr)
			throws Exception {
		/*
		 * 生成页脚段落 给段落设置宽度为占满一行 为公司图标左对齐，页码右对齐创造条件
		 */
		CTDocument1 document = doc.getDocument();
		CTBody body = document.getBody();
		if(sectPr == null) {
			sectPr = body.getSectPr();
			if(sectPr == null) {
				sectPr = body.addNewSectPr();
			}
		}
		setPageSize(doc, sectPr);
		CTPageNumber pageNumber = sectPr.addNewPgNumType();
		pageNumber.setStart(BigInteger.valueOf(1));//页号重新从1开始
		pageNumber.setFmt(STNumberFormat.UPPER_ROMAN);//页号重新从1开始
		XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);
		XWPFFooter footer = headerFooterPolicy.createFooter(STHdrFtr.DEFAULT);
		
		CTSectPr bodySect = doc.getDocument().getBody().getSectPr();
		List<CTHdrFtrRef> hfRef = bodySect.getFooterReferenceList();
		for(int i = 0; i < hfRef.size(); i++) {
			bodySect.removeFooterReference(i);
		}
		
		sectPr.addNewFooterReference().setId(footer.getPackageRelationship().getId());	
		
		XWPFParagraph paragraph = footer.getParagraphArray(0);
		paragraph.setAlignment(ParagraphAlignment.CENTER);
		paragraph.setVerticalAlignment(TextAlignment.CENTER);
		paragraph.setBorderTop(Borders.THICK);
		paragraph.getCTP().getPPr().getPBdr().getTop().setSz(BigInteger.valueOf(6));//解决WPS边线不显示
//		CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
//		tabStop.setVal(STTabJc.RIGHT);
//		int twipsPerInch = 1440;
//		tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

		/*
		 * 生成页码 页码居中
		 */

		XWPFRun run = paragraph.createRun();
		CTFldChar fldChar = run.getCTR().addNewFldChar();
		fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

		run = paragraph.createRun();
		CTText ctText = run.getCTR().addNewInstrText();
		ctText.setStringValue("PAGE  \\* MERGEFORMAT");
		fldChar = run.getCTR().addNewFldChar();
		fldChar.setFldCharType(STFldCharType.Enum.forString("separate"));
		ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
		setXWPFRunStyle(run, "Times New Roman", 9);

		fldChar = run.getCTR().addNewFldChar();
		fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
	}

	/**
	 * 设置页脚的字体样式
	 * 
	 * @param r1
	 *            段落元素
	 */
	private static void setXWPFRunStyle(XWPFRun r1, String font, int fontSize) {
		r1.setFontSize(fontSize);
		CTRPr rpr = r1.getCTR().isSetRPr() ? r1.getCTR().getRPr() : r1.getCTR().addNewRPr();
		CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();
		fonts.setAscii(font);
		fonts.setEastAsia(font);
		fonts.setHAnsi(font);
	}

	/**
	 * 增加自定义标题样式。这里用的是stackoverflow的源码
	 * 
	 * @param docxDocument
	 *            目标文档
	 * @param strStyleId
	 *            样式名称
	 * @param headingLevel
	 *            样式级别
	 */
	public static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId,
			int headingLevel, String fontFamily, String fontSize) {

		CTStyle ctStyle = CTStyle.Factory.newInstance();
		ctStyle.setStyleId(strStyleId);
		
		CTRPr pRpr = ctStyle.getRPr();
        if (pRpr == null) {  
            pRpr = ctStyle.addNewRPr();
        }
		//设置字体
		CTFonts fonts = pRpr.isSetRFonts() ? pRpr.getRFonts() : pRpr  
	                .addNewRFonts();  
        fonts.setAscii(fontFamily);  
        fonts.setEastAsia(fontFamily);  
        fonts.setHAnsi(fontFamily);
        
        // 设置字体大小  
        CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();  
        sz.setVal(new BigInteger(fontSize));  
  
        CTHpsMeasure szCs = pRpr.isSetSzCs() ? pRpr.getSzCs() : pRpr  
                .addNewSzCs();  
        szCs.setVal(new BigInteger(fontSize));

		CTString styleName = CTString.Factory.newInstance();
		styleName.setVal(strStyleId);
		ctStyle.setName(styleName);

		CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
		indentNumber.setVal(BigInteger.valueOf(headingLevel));

		// lower number > style is more prominent in the formats bar
		ctStyle.setUiPriority(indentNumber);

		CTOnOff onoffnull = CTOnOff.Factory.newInstance();
		ctStyle.setUnhideWhenUsed(onoffnull);

		// style shows up in the formats bar
		ctStyle.setQFormat(onoffnull);

		// style defines a heading of the given level
		CTPPr ppr = CTPPr.Factory.newInstance();
		ppr.setOutlineLvl(indentNumber);
		ctStyle.setPPr(ppr);

		XWPFStyle style = new XWPFStyle(ctStyle);

		// is a null op if already defined
		XWPFStyles styles = null;
		if(docxDocument.getStyles() == null) {
			styles = docxDocument.createStyles();
		} else {
			styles = docxDocument.getStyles();
		}

		style.setType(STStyleType.PARAGRAPH);
		styles.addStyle(style);

	}
	
	/**
	 * 创建编号样式
	 * @param doc
	 * @param lvlText
	 * @param stNumberFmt
	 * @return
	 * @throws XmlException
	 */
	public static BigInteger createNumStyle(XWPFDocument doc, String lvlText, STNumberFormat.Enum stNumberFmt) throws XmlException {
		XWPFNumbering numbering = doc.getNumbering();
		if(numbering == null) {
			numbering = doc.createNumbering();
		}
		CTAbstractNum ctAbstractNum = CTAbstractNum.Factory.parse("<xml-fragment xmlns:wpc='http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas'"
				+ " xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006'"
				+ " xmlns:o='urn:schemas-microsoft-com:office:office'"
				+ " xmlns:r='http://schemas.openxmlformats.org/officeDocument/2006/relationships'"
				+ " xmlns:m='http://schemas.openxmlformats.org/officeDocument/2006/math'"
				+ " xmlns:v='urn:schemas-microsoft-com:vml' xmlns:wp14='http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing'"
				+ " xmlns:wp='http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'"
				+ " xmlns:w10='urn:schemas-microsoft-com:office:word'"
				+ " xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'"
				+ " xmlns:w14='http://schemas.microsoft.com/office/word/2010/wordml'"
				+ " xmlns:wpg='http://schemas.microsoft.com/office/word/2010/wordprocessingGroup'"
				+ " xmlns:wpi='http://schemas.microsoft.com/office/word/2010/wordprocessingInk'"
				+ " xmlns:wne='http://schemas.microsoft.com/office/word/2006/wordml'"
				+ " xmlns:wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape'"
				+ " mc:Ignorable='w14 wp14'>"
				+ "<w:nsid w:val='" + UUIDUtils.getEntryStr() + "' />"//1656060D
				+ "<w:multiLevelType w:val='hybridMultilevel' />"
				+ "<w:tmpl w:val='" + UUIDUtils.getEntryStr() + "' />"//99FCFC1A
				+ "<w:lvl w:ilvl='0' w:tplc='0409000F'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='" + stNumberFmt + "' />"
				+ "<w:suff w:val='nothing' />" //编号后没有制表符
				+ "<w:lvlText w:val='" + lvlText + "' />"
				+ "<w:lvlJc w:val='left' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='570' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='570' w:hanging='570' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='1' w:tplc='04090019' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='lowerLetter' />"
				+ "<w:lvlText w:val='%2.' />"
				+ "<w:lvlJc w:val='left' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='840' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='840' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='2' w:tplc='0409001B' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='lowerRoman' />"
				+ "<w:lvlText w:val='%3.' />"
				+ "<w:lvlJc w:val='right' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='1260' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='1260' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='3' w:tplc='0409000F' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='decimal' />"
				+ "<w:lvlText w:val='%4.' />"
				+ "<w:lvlJc w:val='left' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='1680' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='1680' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='4' w:tplc='04090019' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='lowerLetter' />"
				+ "<w:lvlText w:val='%5.' />"
				+ "<w:lvlJc w:val='left' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='2100' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='2100' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='5' w:tplc='0409001B' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='lowerRoman' />"
				+ "<w:lvlText w:val='%6.' />"
				+ "<w:lvlJc w:val='right' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='2520' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='2520' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='6' w:tplc='0409000F' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='decimal' />"
				+ "<w:lvlText w:val='%7.' />"
				+ "<w:lvlJc w:val='left' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='2940' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='2940' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='7' w:tplc='04090019' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='lowerLetter' />"
				+ "<w:lvlText w:val='%8.' />"
				+ "<w:lvlJc w:val='left' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='3360' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='3360' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "<w:lvl w:ilvl='8' w:tplc='0409001B' w:tentative='1'>"
				+ "<w:start w:val='1' />"
				+ "<w:numFmt w:val='lowerRoman' />"
				+ "<w:lvlText w:val='%9.' />"
				+ "<w:lvlJc w:val='right' />"
				+ "<w:pPr>"
				+ "<w:tabs>"
				+ "	<w:tab w:val='num' w:pos='3780' />"
				+ "</w:tabs>"
				+ "<w:ind w:left='3780' w:hanging='420' />"
				+ "</w:pPr>"
				+ "</w:lvl>"
				+ "</xml-fragment>");
		XWPFAbstractNum abstractNum = new XWPFAbstractNum(ctAbstractNum);
		
		BigInteger id = BigInteger.valueOf(0);
        boolean found = false;
        while (!found)
        {
            Object o = numbering.getAbstractNum(id);
            found = (o == null);
            if (!found) id = id.add(BigInteger.ONE);
        }		
		
        ctAbstractNum.setAbstractNumId(id);
		
		id = numbering.addAbstractNum(abstractNum);
		return doc.getNumbering().addNum(id);
	}
	
	/**
	 * 设置段落文字居左、居中、居右
	 * @param p
	 * @param pAlign
	 * @param valign
	 */
	public void setParagraphAlignInfo(XWPFParagraph p,  
            ParagraphAlignment pAlign, TextAlignment valign) {  
        p.setAlignment(pAlign);  
        p.setVerticalAlignment(valign);  
    }
	
	/**
	 * 设置段落首行缩进
	 * @param p
	 * @param firstChar
	 */
	public static void setParagraphFirstLine(XWPFParagraph p, double firstChar) {  
        CTPPr pPPr = null;  
        if (p.getCTP() != null) {  
            if (p.getCTP().getPPr() != null) {  
                pPPr = p.getCTP().getPPr();  
            } else {  
                pPPr = p.getCTP().addNewPPr();  
            }  
        }
        CTInd ctInd = pPPr.getInd() != null ? pPPr.getInd() : pPPr.addNewInd();
        ctInd.setLeft(BigInteger.ZERO);
        ctInd.setFirstLineChars(BigInteger.valueOf((int) (firstChar * 100)));
        ctInd.setFirstLine(BigInteger.valueOf((int)(firstChar * 240)));
    }
	
	/**
	 * 设置段落对齐方式
	 * @param p
	 * @param alignValue
	 */
	public static void setParagraphAlign(XWPFParagraph p, STJc.Enum alignValue) {
		CTPPr pPPr = null;  
        if (p.getCTP() != null) {  
            if (p.getCTP().getPPr() != null) {  
                pPPr = p.getCTP().getPPr();  
            } else {  
                pPPr = p.getCTP().addNewPPr();  
            }  
        } 
        
        //设置两端对齐
//      CTParaRPr rPr = pPPr.getRPr() == null ? pPPr.addNewRPr() : pPPr.getRPr();
        CTJc ctJc = pPPr.getJc() == null ? pPPr.addNewJc() : pPPr.getJc();
        ctJc.setVal(alignValue);
	}
	
	/**
	 * 设置段落段前段后磅数、段前段后间距、段前段后行数、间距
	 * @param p
	 * @param isSpace
	 * @param before
	 * @param after
	 * @param isPLine
	 * @param beforeLines
	 * @param afterLines
	 * @param isLine
	 * @param line
	 * @param lineValue
	 */
	public static void setParagraphSpacingInfo(XWPFParagraph p, boolean isSpace,  
            String before, String after, boolean isPLine, String beforeLines,  
            String afterLines, boolean isLine, String line,  
            STLineSpacingRule.Enum lineValue) {  
        CTPPr pPPr = null;  
        if (p.getCTP() != null) {  
            if (p.getCTP().getPPr() != null) {  
                pPPr = p.getCTP().getPPr();  
            } else {  
                pPPr = p.getCTP().addNewPPr();  
            }  
        } 
        
        //设置两端对齐
        CTJc ctJc = pPPr.getJc() == null ? pPPr.addNewJc() : pPPr.getJc();
        ctJc.setVal(STJc.BOTH);
        
        CTSpacing pSpacing = pPPr.getSpacing() != null ? pPPr.getSpacing()  
                : pPPr.addNewSpacing();  
        if (isSpace) {  
            // 段前磅数  
            if (before != null) {  
                pSpacing.setBefore(new BigInteger(before));  //p.setSpacingBefore(before);
            }  
            // 段后磅数  
            if (after != null) {  
                pSpacing.setAfter(new BigInteger(after));  // p.setSpacingAfter(after);
            }  
        }  
        if (isPLine) {  
            // 段前行数  
            if (beforeLines != null) {  
                pSpacing.setBeforeLines(new BigInteger(beforeLines));  //p.setSpacingBeforeLines(beforeLines);
            }  
            // 段后行数  
            if (afterLines != null) {  
                pSpacing.setAfterLines(new BigInteger(afterLines));  //p.setSpacingAfterLines(afterLines);
            }  
        }  
        // 间距  
        if (isLine) {  
            if (line != null) {  
                pSpacing.setLine(new BigInteger(line));  
            }  
            if (lineValue != null) {  
                pSpacing.setLineRule(lineValue);  //p.setSpacingLineRule(LineSpacingRule.AUTO);
            }  
        }  
    }
	
	/**
	 * 设置段落文本样式
	 * @param pRun
	 * @param fontFamily
	 * @param fontSize
	 */
	public static void setParagraphTextStyleInfo(XWPFRun pRun, String fontFamily, String fontSize) {
  
        CTRPr pRpr = null;  
        if (pRun.getCTR() != null) {  
            pRpr = pRun.getCTR().getRPr();  
            if (pRpr == null) {  
                pRpr = pRun.getCTR().addNewRPr();
            }  
        }  
  
        // 设置字体  
        CTFonts fonts = pRpr.isSetRFonts() ? pRpr.getRFonts() : pRpr  
                .addNewRFonts();  
        fonts.setAscii(fontFamily);  
        fonts.setEastAsia(fontFamily);  
        fonts.setHAnsi(fontFamily);  
  
        // 设置字体大小  
        CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();  
        sz.setVal(new BigInteger(fontSize));  
  
        CTHpsMeasure szCs = pRpr.isSetSzCs() ? pRpr.getSzCs() : pRpr  
                .addNewSzCs();  
        szCs.setVal(new BigInteger(fontSize)); 
    }
	
	/**
	 * 添加分节符
	 * @param p
	 */
	public static CTSectPr addNewSection(XWPFParagraph p) {
		CTPPr pPPr = p.getCTP().addNewPPr();
    	CTSectPr ctSectPr = pPPr.addNewSectPr();
    	return ctSectPr;
    }
	
	public static void setTOCStyle(XWPFDocument document) throws XmlException {
		String cTStyleTOC1 ="<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"TOC1\">"
                + "<w:name w:val=\"toc 1\"/>"
                + "<w:basedOn w:val=\"Normal\"/>"
                + "<w:next w:val=\"Normal\"/>"
                + "<w:autoRedefine/><w:unhideWhenUsed/>"
                + "<w:rPr><w:sz w:val=\"24\"/><w:szCs w:val=\"24\"/></w:rPr>"
                + "<w:pPr><w:spacing w:before=\"0\" w:after=\"0\" w:line=\"360\" w:lineRule=\"auto\" /></w:pPr>"
                + "</w:style>";

		String cTStyleTOC2 ="<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"TOC2\">"
                + "<w:name w:val=\"toc 2\"/>"
                + "<w:basedOn w:val=\"Normal\"/>"
                + "<w:next w:val=\"Normal\"/>"
                + "<w:autoRedefine/><w:unhideWhenUsed/>"
                + "<w:rPr><w:sz w:val=\"24\"/><w:szCs w:val=\"24\"/></w:rPr>"
                + "<w:pPr><w:ind w:leftChars=\"200\" w:left=\"420\" /><w:spacing w:before=\"0\" w:after=\"0\" w:line=\"360\" w:lineRule=\"auto\" /></w:pPr>"
                + "</w:style>";

		String cTStyleTOC3 ="<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"TOC3\">"
                + "<w:name w:val=\"toc 3\"/>"
                + "<w:basedOn w:val=\"Normal\"/>"
                + "<w:next w:val=\"Normal\"/>"
                + "<w:autoRedefine/><w:unhideWhenUsed/>"
                + "<w:rPr><w:sz w:val=\"24\"/><w:szCs w:val=\"24\"/></w:rPr>"
                + "</w:style>";
		XWPFStyles styles = null;
		if(document.getStyles() == null) {
			styles = document.createStyles();
		} else {
			styles = document.getStyles();
		}
	    CTStyles cTStyles = CTStyles.Factory.parse(cTStyleTOC1);
	    CTStyle cTStyle = cTStyles.getStyleArray(0);
	    styles.addStyle(new XWPFStyle(cTStyle));
	    cTStyles = CTStyles.Factory.parse(cTStyleTOC2);
	    cTStyle = cTStyles.getStyleArray(0);
	    styles.addStyle(new XWPFStyle(cTStyle));
	    cTStyles = CTStyles.Factory.parse(cTStyleTOC3);
	    cTStyle = cTStyles.getStyleArray(0);
	    styles.addStyle(new XWPFStyle(cTStyle));
	}
}
